using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Linq;
using RobotWebApiService.Services;

namespace RobotWebApiService.Services
{
    public class PermissionAuthorizationFilter : IAuthorizationFilter
    {
        private readonly JwtService _jwtService;

        public PermissionAuthorizationFilter(JwtService jwtService)
        {
            _jwtService = jwtService;
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            if (context.ActionDescriptor.EndpointMetadata.Any(em => em is Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute))
                return;

            var permissionAttribute = context.ActionDescriptor.EndpointMetadata
                .OfType<PermissionAttribute>()
                .FirstOrDefault();

            if (permissionAttribute == null) return;

            var token = context.HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");

            try
            {
                var principal = _jwtService.ValidateToken(token);
                var permissions = principal.Claims
                    .Where(c => c.Type == "permission")
                    .Select(c => c.Value)
                    .ToList();

                if (!permissions.Contains(permissionAttribute.PermissionCode))
                {
                    context.Result = new ForbidResult();
                }
            }
            catch
            {
                context.Result = new UnauthorizedResult();
            }
        }
    }

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class PermissionAttribute : Attribute
    {
        public string PermissionCode { get; }

        public PermissionAttribute(string code)
        {
            PermissionCode = code;
        }
    }
}